package cn.jiadakeji.parent.service;

import cn.hutool.core.util.PhoneUtil;
import cn.hutool.core.util.RandomUtil;
import cn.jiadakeji.parent.common.constant.RedisPrefixConstants;
import cn.jiadakeji.parent.common.core.redis.RedisCache;
import cn.jiadakeji.parent.common.exception.CustomException;
import cn.jiadakeji.parent.common.util.AliyunSmsUtils;
import cn.jiadakeji.parent.common.util.WechatUtils;
import cn.jiadakeji.parent.domain.Customer;
import cn.jiadakeji.parent.domain.CustomerParentPart;
import cn.jiadakeji.parent.domain.StudentParent;
import cn.jiadakeji.parent.dto.CustomerJwtDTO;
import cn.jiadakeji.parent.dto.CustomerParentPartDTO;
import cn.jiadakeji.parent.dto.LoginRetDTO;
import cn.jiadakeji.parent.mapper.CustomerMapper;
import cn.jiadakeji.parent.mapper.CustomerParentPartMapper;
import cn.jiadakeji.parent.mapper.StudentParentMapper;
import cn.jiadakeji.parent.vo.PasswordLoginVO;
import cn.jiadakeji.parent.vo.SmsLoginVO;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author hhaoyu
 */
@Service
public class CustomerService {

    @Resource
    private CustomerMapper customerMapper;
    @Resource
    private CustomerParentPartMapper customerParentPartMapper;
    @Resource
    private StudentParentMapper studentParentMapper;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private TokenService tokenService;

    public LoginRetDTO wechatLogin(String openIdCode){
//        CustomerParentPart customerParentPart = new CustomerParentPart();
//        JSONObject wechatLoginRet =  WechatUtils.jscode2session(openIdCode);
//        String openId = wechatLoginRet.getString("openid");
//        customerParentPart.setOpenId(openId);
//        if(null == openId){
//            throw new CustomException(-1, "换取openId失败");
//        }
        String openId = openIdCode;
        CustomerParentPart customerParentPart = new CustomerParentPart();
        customerParentPart.setOpenId(openId);
        if(null == openId){
            throw new CustomException(-1, "换取openId失败");
        }
        CustomerParentPartDTO ctpb = customerParentPartMapper.selectOneByOpenId(customerParentPart);

        if(null == ctpb || null == ctpb.getCustomer()){
            LoginRetDTO loginRetDTO = new LoginRetDTO();
            loginRetDTO.setOpenId("abcd");
            throw new CustomException(-2,"用户不存在",loginRetDTO);
        }

        LoginRetDTO loginRetDTO =  this.login(ctpb);
        if(null == loginRetDTO){
            throw new CustomException(-1, "获取token失败");
        }
        return loginRetDTO;
    }

    public boolean sendVerifySms(String phone){
        String verifyCode = RandomUtil.randomNumbers(6);
        Map<String, String> templateParam = new HashMap<>();
        templateParam.put("code",verifyCode );
        boolean isSuc = AliyunSmsUtils.send(AliyunSmsUtils.VerifySmsCode,templateParam, Collections.singletonList(phone));
        redisCache.setCacheObject(RedisPrefixConstants.verifyPrefix + phone, verifyCode, 15, TimeUnit.MINUTES);
        return isSuc;
    }

    @Transactional
    public LoginRetDTO smsLogin(SmsLoginVO smsLoginVO){
        String phone = smsLoginVO.getPhone();
        String verifyCode = redisCache.getCacheObject(RedisPrefixConstants.verifyPrefix + phone);
        if(null == verifyCode){
            throw new CustomException(-1, "验证码已失效");
        }

        if(!verifyCode.equals(smsLoginVO.getVerifyCode())){
            throw new CustomException(-1, "验证码输入错误");
        }

        CustomerParentPart customerParentPart = new CustomerParentPart();
        StudentParent studentParent = new StudentParent();
        Customer customer = customerMapper.selectOne(new QueryWrapper<Customer>().eq("phone", smsLoginVO.getPhone()));
        if(customer == null){
            customer = new Customer();
            customer.setPhone(smsLoginVO.getPhone());
            customerMapper.insert(customer);

            studentParent.setPhone(smsLoginVO.getPhone());
            studentParentMapper.insert(studentParent);

            customerParentPart.setOpenId(smsLoginVO.getOpenId());
            customerParentPart.setCustomerId(customer.getId());
            customerParentPart.setStudentParentId(studentParent.getId());
            customerParentPartMapper.insert(customerParentPart);
        }

        CustomerJwtDTO customerJwtDTO = new CustomerJwtDTO();
        BeanUtils.copyProperties(customer, customerJwtDTO);
        customerJwtDTO.setOpenId(customerParentPart.getOpenId());
        customerJwtDTO.setStudentParentId(studentParent.getId());
        customerJwtDTO.setCustomerParentPartId(customerParentPart.getId());
        LoginRetDTO loginRetDTO =  tokenService.login(customerJwtDTO);
        if(null == loginRetDTO){
            throw new CustomException(-1, "获取token失败");
        }
        redisCache.deleteObject(RedisPrefixConstants.verifyPrefix + phone);
        return loginRetDTO;
    }

    public LoginRetDTO passwordLogin(PasswordLoginVO passwordLoginVO){
        boolean isPhone = PhoneUtil.isMobile(passwordLoginVO.getUsername());
        CustomerParentPart customerParentPart = new CustomerParentPart();
        Customer customer = new Customer();
        if(isPhone){
            customer.setPhone(passwordLoginVO.getUsername());
        }else {
            customer.setUserName(passwordLoginVO.getUsername());
        }
        CustomerParentPartDTO customerParentPartDTO = customerMapper.selectOneByPhone(customer);
        if(null == customerParentPartDTO || null == customerParentPartDTO.getCustomer()){
            throw new CustomException(-1, "用户不存在请联系管理员添加");
        }
        LoginRetDTO loginRetDTO = this.login(customerParentPartDTO);
        if(null == loginRetDTO){
            throw new CustomException(-1, "获取token失败");
        }
        return loginRetDTO;
    }

    private LoginRetDTO login(CustomerParentPartDTO customerParentPartDTO){
        CustomerJwtDTO customerJwtDTO = new CustomerJwtDTO();
        BeanUtils.copyProperties( customerParentPartDTO.getCustomer() , customerJwtDTO);

        customerJwtDTO.setCustomerParentPartId(customerParentPartDTO.getCustomerParentPartId());
        customerJwtDTO.setStudentParentId(customerParentPartDTO.getStudentParent().getId());
        customerJwtDTO.setOpenId(customerParentPartDTO.getOpenId());
        return tokenService.login(customerJwtDTO);
    }

    public LoginRetDTO refreshAccessToken(String refreshToken){
        String customerId = tokenService.getCustomerIdFromRefreshToken(refreshToken);
        if(null == customerId){
            throw new CustomException(-1, "refreshToken 失效");
        }

        CustomerJwtDTO customerJwtDTO = customerMapper.selectCustomerJwtDTOById(customerId);
        if(null == customerJwtDTO){
            throw new CustomException(-1, "找不到用户");
        }
        String accessToken = tokenService.createToken(customerJwtDTO);
        LoginRetDTO loginRetDTO = new LoginRetDTO();
        loginRetDTO.setAccessToken(accessToken);
        return loginRetDTO;
    }


}
